﻿#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>

using namespace std;

//初始化列表

class Time
{
public:
	Time(int hour)
		:_hour(hour)
	{
		cout << "Time()" << endl;
	}
private:
	int _hour;
};

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
		//初始化列表:
		:_ref(_year)
		, _t(12)
		, _n(_day)
		, _day(day)
		, _month(month)
		, _year(year)
	{
	}

private:
	int _year;
	int _month;
	int _day;
	Time _t; // 没有默认构造
	int& _ref; // 引⽤
	const int _n; // const
};


//------------------------------------------------------------------------
//                              类和对象下
//------------------------------------------------------------------------

// C++支持内置类型与自定义类型隐式转换 需要构造函数有内置类型的参数
// 自定义类型之间也可以转换 同样需要对应的构造函数
// 关键字 explicit 在构造函数前加上 explicit 关闭自定义类型的隐式类型转换

// 静态成员 static 修饰的成员变量 需要在类外面初始化
// 静态成员函数 仅仅只能访问静态成员

// 友元 friend 提供突破类域的一个方式 
// 友元函数和友元类

// 匿名对象 生命周期只在当前一行 
// const 引用会延长匿名对象的生命周期 使其延长至引用的生命周期

//------------------------------------------------------------------------
//------------------------------------------------------------------------


//int main()
//{
//	Date();//匿名对象
//	Date* ptr = new Date[2]{ 1 };
//
//	delete[] ptr;
//	return 0;
//}


//-----------------------------------------------------------------------
//                                 内存管理
//-----------------------------------------------------------------------
// C++新的管理内存方法 new 和 delete 
// new + 类型[数组] 一个的情况下不需要标注 + []是申请数组 +（初始化值）数组用{}初始化
// delete 释放 new 申请的空间 
// new    会自动调用构造函数初始化申请的空间
// delete 会调用析构函数
// try catch 捕获异常

// new     operator new
// delete  operator delete

// placement-new  对一块已经分配的空间调用构造函数进行初始化 new(指针)class 
        
//------------------------------------------------------------------------                                                                           
//------------------------------------------------------------------------

//int main()
//{
//	Date* ptr = (Date*)operator new(sizeof(Date));
//
//	new(ptr)Date;
//
//	return 0;
//}

//------------------------------------------------------------------------
//                                   模板
//------------------------------------------------------------------------

// 函数模板 :
// template<typename T1,typename T2,........>  定义模板类型
// 模板实例化  
// 隐式实例化：编译器通过实参类型自己推导模板类型实例化函数
// 显示实例化：函数名<类型> 将模板类型实例化为指定类型 一般使用在函数参数中没有模板类型
//           但需要在函数内部使用模板类型 无法自动推导类型 需要显示实例化
// 模板支持与具体函数同时存在 某种意义上构成函数重载  
// 调用原则：有具体先用具体(匹配的情况下)  显示实例化可以强制调用模板函数

// 类模板 :
// 类模板必须显示示例化 类模板的名字不是类型 类模板加实例化参数才是类型
// 模板不支持声明和定义在不同文件中 在函数声明定义分离时指定类域需要重新声明模板参数

//------------------------------------------------------------------------                                                                           
//------------------------------------------------------------------------

//函数模板
template<typename T1>
void Swap(T1 x, T1 y)
{
	T1 tmp = x;
	x = y;
	y = tmp;
}

void Swap(int x, int y)
{
	int tmp = x;
	x = y;
	y = tmp;
}

//类模板
template<typename T1>
class Stack
{
	//...
	void Push(T1 x);

private:
	T1* _a;
	size_t _top;
	size_t _capacity;
};

//重新声明模板参数
template<typename T1>
void Stack<T1>::Push(T1 x)
{
	//...
}

int main()
{
	int a = 10, b = 15;
	Swap(a, b);       // 此处调用具体函数
	Swap<int>(a, b);  // 此处调用显示实例化后的模板函数

	return 0;
}